Ext.ns('AIR2.Drawer');
/***************
 * AIR2 Drawer BinListSingle Component
 *
 * A dataview for displaying the contents of a single Bin. Also allows editing
 * Bin metadata.
 *
 * @class AIR2.Drawer.BinListSingle
 * @extends PIN.LiveDataView
 * @cfg {Object/Array} inlineData
 *   Data radix to load inline, rather than issuing an ajax call.
 * @cfg {Object} inlineParams
 *   Parameters to use with any loaded inlineData, usually {limit:5, self:1}.
 * @cfg {Object} inlineBin
 *   The Bin to load inline (inlineData contains Bin-contents)
 * @cfg {Ext.data.Record} binRec
 *   If not loading inline, you must provide the record for the Bin to view.
 * @cfg {HTMLElement} infoEl
 *   The element above the drawer header, into which this view will render Bin
 *   metadata and editing components.
 *
 */
AIR2.Drawer.BinListSingle = function(config) {
    if (!config) config = {};

    // check for a valid bin record
    if (!config.binRec && !config.inlineBin) {
        Logger("Error: must define a bin record for AIR2.Drawer.BinListSingle!");
        return;
    }

    // create store to interact with base Bin
    var baseRec = config.binRec;
    var baseCfg = {
        url: AIR2.HOMEURL + '/batch.json',
        restful: true,
        writer: new Ext.data.JsonWriter({
            encode: true,
            writeAllFields: false
        }),
        autoSave: false,
        listeners: {
            save: function() {
                this.endEdit(false);
            },
            scope: this
        }
    };
    if (config.inlineBin) {
        baseCfg.data = config.inlineBin;
        this.baseStore = new Ext.data.JsonStore(baseCfg);
        baseRec = this.baseStore.getAt(0);
    }
    else {
        var cpy = 'fields,idProperty,messageProperty,root,successProperty,totalProperty';
        Ext.copyTo(baseCfg, baseRec.store.writer.meta, cpy);
        this.baseStore = new Ext.data.JsonStore(baseCfg);
    }

    // setup the load params
    var p = config.inlineParams || {};
    var inlineLoad = (config.inlineData) ? true : false;
    var mySort = {};
    var myParams = {};
    var typ = baseRec.get('batch_type');
    mySort.field     = p.sort || 'src_last_name';
    mySort.direction = p.dir  || 'ASC';
    myParams.q       = p.q    || null;
    var myUrl = AIR2.HOMEURL+'/batch/'+baseRec.get('batch_uuid')+'/contents.json';
    // etc...

    // create store to interact with the Bin-URL
    var storeCfg = {
        url: myUrl,
        pageSize: 100,
        remoteSort: true,
        baseParams: myParams,
        sortInfo: mySort,
        autoLoad: true,
        autoSave: false,
        autoDestroy: true,
        restful: true,
        writer: new Ext.data.JsonWriter({
            encode: true,
            writeAllFields: false
        }),
        listeners: {
            load: function(store, recs, opt) {
                if (!inlineLoad) AIR2.Drawer.STATE.set('params', opt.params);
                else inlineLoad = false;
            }
        }
    };
    if (config.inlineData) {
        this.skipAnimation = true; //skip infobar animation ONCE
        storeCfg.data = config.inlineData;
    }
    this.store = new PIN.LiveJsonStore(storeCfg);

    // create the bin info header
    this.infoEl = config.infoEl;
    this.infoBar = new AIR2.UI.DataView({
        cls: 'air2-bin-infobar',
        width: config.infoWidth,
        renderTo: config.infoEl,
        store: this.baseStore,
        itemSelector: '.air2-drawer-batch',
        tpl: new Ext.XTemplate(
            '<tpl for=".">' +
              '<div class="air2-drawer-batch">' +
                '<div class="top">' +
                  '<span class="title">{batch_name}</span>' +
                  '<span class="buttons"></span>' +
                '</div>' +
                '<div class="about air2-corners3">' +
                  '<div class="meta">' +
                    'Created by {[AIR2.Format.userName(values.User, true)]} ' +
                    'on {[AIR2.Format.date(values.batch_cre_dtim)]}' +
                    '{[this.formatShared(values)]}' +
                  '</div>' +
                  '<div class="desc">{[this.formatDesc(values.batch_desc)]}</div>' +
                '</div>' +
              '</div>' +
            '</tpl>',
            {
                compiled: true,
                formatDesc: function(desc) {
                    return (desc && desc.length > 0) ? desc : '<i>(No Description Given)</i>';
                },
                formatShared: function(values) {
                    if (values.batch_public_flag)
                        return '<span class="air2-corners3 sharing public">Shared</span>';
                    else
                        return '<span class="air2-corners3 sharing">Not Shared</span>';
                }
            }
        )
    });

    // configure the body items
    var s = this.store.getSortState();
    var nameSort = (s.field == 'src_last_name') ? ((s.direction == 'ASC') ? 'desc' : 'asc') : '';
    var emlSort = (s.field == 'sort_email') ? ((s.direction == 'ASC') ? 'desc' : 'asc') : '';
    var locSort = (s.field == 'sort_city') ? ((s.direction == 'ASC') ? 'desc' : 'asc') : '';
    this.headers = new Ext.BoxComponent({
        cls: 'header',
        html: '<table class="source-item"><tr>' +
                '<td class="index"> </td>' +
                '<td class="name '+nameSort+'"><span>Name</span></td>' +
                '<td class="email '+emlSort+'"><span>Email</span></td>' +
                '<td class="location '+locSort+'"><span>Location</span></td>' +
              '</tr></table>'
    });
    this.livedv = new PIN.LiveDataView({
        emptyText: '<div class="air2-empty"><h3>Empty Bin</h3></div>',
        selectedClass: 'row-selected',
        overClass: 'row-over',
        multiSelect: true,
        store: this.store,
        setTemplateType: function(type) {
            if (type == 'S') {
                this.tpl = new Ext.XTemplate(
                    '<table class="source-item"><tr>' +
                      '<td class="index">{[values.index+1]}.</td>' +
                      '<td class="name">{[AIR2.Format.sourceName(values.Source, true)]}</td>' +
                      '<td class="email">{[this.formatEmail(values.Source)]}</td>' +
                      '<td class="location">{[this.formatLocation(values.Source)]}</td>' +
                      //'<tpl for="BatchRelated">' +
                      //  '{[this.printRelated(values)]}' +
                      //'</tpl>' +
                    '</tr></table>',
                    {
                        compiled: true,
                        disableFormats: true,
                        formatLocation: function(src) {
                            var str = '';
                            if (src.SrcMailAddress.length > 0) {
                                var ma = src.SrcMailAddress[0];
                                if (ma.smadd_city && ma.smadd_state) {
                                    str += ma.smadd_city+', '+ma.smadd_state;
                                }
                                else if (ma.smadd_state) {
                                    str += ma.smadd_state;
                                }
                                else if (ma.smadd_zip) {
                                    str += ma.smadd_zip;
                                }
                                else if (ma.smadd_cntry) {
                                    str += ma.smadd_cntry;
                                }
                            }
                            return str;
                        },
                        formatEmail: function(src) {
                            var str = '';
                            if (src.SrcEmail.length > 0) {
                                var eml = src.SrcEmail[0].sem_email;
                                var abbr = Ext.util.Format.ellipsis(eml, 25);
                                str += AIR2.Format.createLink(abbr, 'mailto:'+eml, true, true);
                            }
                            return str;
                        }
                    }
                );
            }
            else {
                this.tpl = new Ext.XTemplate(
                    '<div><h3>No template defined for bin type="{bitem_type}"</h3></div>',
                    {compiled: true, disableFormats: true}
                );
            }
        }
    });

    // important: set the record BEFORE calling parent constructor
    this.setRecord(baseRec, true);

    // call parent constructor
    config.items = [this.headers, this.livedv];
    AIR2.Drawer.BinListSingle.superclass.constructor.call(this, config);

    // fix livedv height/width
    var newHeight = Ext.getCmp('air2-drawer').sizes.si.height - this.headers.getHeight();
    this.livedv.setHeight(newHeight);

    // sort listeners
    var sorts = ['.name', '.email', '.location'];
    var flds = ['src_last_name', 'sort_email', 'sort_city'];
    this.headers.el.on('click', function(ev) {
        for (var i=0; i<sorts.length; i++) {
            if (el = ev.getTarget(sorts[i], 3, true)) {
                if (el.hasClass('desc')) {
                    el.radioClass(['desc', 'asc']);
                    el.removeClass('desc');
                    this.store.sortInfo = {field: flds[i], direction: 'DESC'};
                }
                else {
                    el.radioClass(['desc', 'asc']);
                    el.removeClass('asc');
                    this.store.sortInfo = {field: flds[i], direction: 'ASC'};
                }
                this.reloadDataView();
            }
        }
    }, this);
}
Ext.extend(AIR2.Drawer.BinListSingle, Ext.Container, {
    cls: 'air2-binlist air2-binlist-single air2-drawer-batch',
    reloadDataView: function() {
        this.livedv.reloadDataView();
    },
    setRecord: function(rec, skipSort) {
        this.binRecord = rec;

        // set the STATE uuid
        var uuid = rec.get('batch_uuid');
        if (AIR2.Drawer.STATE.get('uuid') != uuid)
            AIR2.Drawer.STATE.set('uuid', uuid);

        // setup the base store
        if (this.uuid != uuid) {
            this.baseStore.removeAll(true); //silent
            this.baseStore.add(rec);
            this.uuid = uuid;
        }
        this.showInfo(); //show infobar dataview

        // setup sorting for this type
        if (!skipSort) {
            var typ = rec.get('batch_type');
            var srt = AIR2.Drawer.Config.SORTFIELDS.si[typ];
            if (srt) this.store.setDefaultSort(srt[0].fld, srt[0].dir);
        }

        // update the store url
        var newUrl = AIR2.HOMEURL+'/batch/'+rec.get('batch_uuid')+'/contents.json';
        if (this.store.proxy.url != newUrl) {
            this.store.proxy.setUrl(newUrl, true);
        }

        // update the template
        if (rec.get('batch_type') != this.tplType) {
            this.tplType = rec.get('batch_type');
            this.livedv.setTemplateType(this.tplType);
        }
    },
    applyFilter: function(value, noMask) {
        this.store.setBaseParam('q', value);
        this.livedv.reloadDataView(noMask);
    },
    getBinRecord: function(target) {
        return this.binRecord;
    },
    refreshBin: function(target) {
        this.livedv.store.on('load', function() {
            this.el.unmask();
        }, this, {single: true});
        var fld = Ext.getCmp('air2-drawer').tbar.get(1);
        fld.reset();
        this.applyFilter('', true); // reload w/o livedv mask
    },
    maskBin: function(target) {
        this.el.mask('Adding');
    },
    showInfo: function() {
        this.infoBar.refresh();
        this.showInfoButtons();
        var b = this.infoBar;
        if (this.skipAnimation) {
            this.skipAnimation = false;
            this.infoEl.setHeight(b.el.getComputedHeight());
            b.el.show();
        }
        else {
            this.infoEl.setHeight(
                b.el.getComputedHeight(),
                {duration: .2, callback: function() {
                    b.el.fadeIn();
                }}
            );
        }
    },
    showInfoButtons: function() {
        // only show edit/delete for owner
        if (this.binRecord.get('batch_owner')) {
            var btns = this.infoBar.el.child('.buttons', true);
            new AIR2.UI.Button({
                air2type: 'DRAWER',
                iconCls: 'air2-icon-editzone',
                text: 'Edit',
                renderTo: btns,
                handler: function() {this.startEdit()},
                scope: this
            });
            new AIR2.UI.Button({
                air2type: 'DRAWER',
                iconCls: 'air2-icon-delete',
                text: 'Delete',
                renderTo: btns,
                handler: function() {this.deleteBin()},
                scope: this
            });
        }
    },
    hideInfo: function() {
        this.infoEl.setHeight(0, {duration:.2});
        this.infoBar.el.fadeOut();
    },
    startEdit: function() {
        if (!this.editForm) {
            this.editForm = new Ext.form.FormPanel({
                cls: 'air2-bin-edit',
                renderTo: this.infoEl,
                style: 'display:none',
                unstyled: true,
                labelWidth: 75,
                items: [{
                    xtype: 'air2remotetext',
                    fieldLabel: 'Bin Name',
                    name: 'batch_name',
                    width: '96%',
                    allowBlank: false,
                    remoteUrl: AIR2.HOMEURL + '/batch/name.json'
                },{
                    xtype: 'textarea',
                    fieldLabel: 'Description',
                    name: 'batch_desc',
                    width: '96%',
                    maxLength: 256
                },{
                    xtype: 'combo',
                    fieldLabel: 'Shared',
                    name: 'batch_public_flag',
                    width: 100,
                    mode: 'local',
                    store: new Ext.data.ArrayStore({
                        id: 0,
                        fields: ['value', 'display'],
                        data: [[false, 'No'], [true, 'Yes']]
                    }),
                    valueField: 'value',
                    displayField: 'display',
                    triggerAction: 'all',
                    forceSelection: true,
                    editable: false
                }],
                bbar: ['->', {
                    xtype: 'air2button',
                    air2type: 'SAVE',
                    air2size: 'MEDIUM',
                    text: 'Save',
                    scope: this,
                    handler: function() {this.endEdit(true)}
                },'   ',{
                    xtype: 'air2button',
                    air2type: 'CANCEL',
                    air2size: 'MEDIUM',
                    text: 'Cancel',
                    scope: this,
                    handler: function() {this.endEdit(false)}
                }]
            });
            this.editForm.el.on('click', function(e) {
                if (e.getTarget('.air2-savebutton')) {
                    this.endEdit(true);
                }
                else if (e.getTarget('.air2-cancelbutton')) {
                    this.endEdit(false);
                }
            }, this);
        }

        var f = this.editForm, r = this.binRecord, b = this.infoBar, el = this.infoEl;
        f.get(0).originalValue = r.get('batch_name');
        f.getForm().loadRecord(r);
        f.el.unmask();
        f.el.show({duration: .2});
        b.el.slideOut('t', {duration: .2, useDisplay: true});
        el.setHeight(f.el.getComputedHeight(), {duration: .2});
    },
    endEdit: function(save) {
        var f = this.editForm, r = this.binRecord, b = this.infoBar, el = this.infoEl, s = this.baseStore;

        // make sure we have something to save
        if (s.getCount() == 0) return;

        if (save) {
            if (!f.getForm().isValid()) return;
            f.getForm().updateRecord(r);
            if (r.dirty) {
                f.el.mask('Saving');
                s.on('save', function() {
                    this.showInfoButtons();
                }, this, {single:true});
                s.save();
            }
        }
        else {
            b.el.slideIn('t', {duration: .3});
            f.el.hide({duration: .2});
            el.setHeight(b.el.getComputedHeight(), {duration: .2});
        }
    },
    deleteBin: function() {
        if (!this.deleteConfirm) {
            var rec = this.binRecord;
            var el = this.infoBar.el.createChild({
                cls: 'delete-confirm air2-corners3',
                html: 'Really delete?<br/><a class="yes">Delete</a><a class="no">Cancel</a>'
            });
            el.on('click', function(ev) {
                if (ev.getTarget('a.yes')) {
                    el.fadeOut({remove:true, callback: function() {
                        var s = rec.store;
                        s.remove(rec);
                        s.save();
                        s.on('save', function() {
                            Ext.getCmp('air2-drawer').transitionView('lg');
                        }, this, {single:true});
                    }});
                }
                else if (ev.getTarget('a.no')) {
                    el.slideOut('t', {duration:.2, remove:true});
                }
            }, this);
            el.alignTo(this.infoBar.el.child('.buttons', true), 't-b');
            el.slideIn('t', {duration:.2});
        }
    }
});